﻿# 
# Cmake的命令不区分打下写，例如message，set等命令；但Cmake的变量区分大小写
# 为统一风格，本项目的Cmake命令全部采用小写，变量全部采用大写加下划线组合。
# 由于很多开发环境是在内网，因此，这里的第三方代码模块使用git的submodule来拉取而不是由ExternalProject_Add来管理
# 这里的ExternalProject_Add针对文件路径进行管理，不针对远程url
# 
# 由于种种原因，每个库的安装路径是不一样的
#  有些的cmake文件安装在lib/cmake目录下（rapidjson,rdkafka,spdlog,tinyxml2,concurrentqueue）
#  有些安装在share/cmake目录下（nlohmann-json,redis++）
#  有些直接安装在share目录下（hiredis）
#  还有一些干脆没有提供cmake（asio，mINI）
# 这个cmake文件是在3rdparty已经编译完的前提下，提供了第三方库引入,减少开发者在此方面所耗费的时间
# 
cmake_minimum_required(VERSION 3.5)
project(cpp-server-scaffolding
        LANGUAGES CXX
        DESCRIPTION "cpp-server-scaffolding"
)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

# The unified installation location of third-party libraries is specified here. You must first execute 3rdparty/CMakeLists.txt
# cn:这里指定第三方库统一的安装位置，你必须先执行3rdparty/CMakeLists.txt
set(CPPSCAFFOLDING_INSTALL_DIR "${CMAKE_CURRENT_LIST_DIR}/install")
set(CPPSCAFFOLDING_INCLUDE_DIR "${CPPSCAFFOLDING_INSTALL_DIR}/include")

########################################################
# 设置CMAKE_PREFIX_PATH
########################################################    
# 保存当前的CMAKE_PREFIX_PATH到临时变量  
set(_ORIGINAL_CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH})  
  
# 清除CMAKE_PREFIX_PATH
set(CMAKE_PREFIX_PATH)  
  
# 追加新路径（这里可以追加多个路径）
list(APPEND CMAKE_PREFIX_PATH "${CPPSCAFFOLDING_INSTALL_DIR}/cmake")
list(APPEND CMAKE_PREFIX_PATH "${CPPSCAFFOLDING_INSTALL_DIR}/lib")
list(APPEND CMAKE_PREFIX_PATH "${CPPSCAFFOLDING_INSTALL_DIR}/lib/cmake")
list(APPEND CMAKE_PREFIX_PATH "${CPPSCAFFOLDING_INSTALL_DIR}/share")
list(APPEND CMAKE_PREFIX_PATH "${CPPSCAFFOLDING_INSTALL_DIR}/share/cmake")
  
# 如果之前有设置CMAKE_PREFIX_PATH，则将其追加回来  
if(_ORIGINAL_CMAKE_PREFIX_PATH)  
    list(APPEND CMAKE_PREFIX_PATH ${_ORIGINAL_CMAKE_PREFIX_PATH})  
endif()  
message(STATUS "CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}")
########################################################
# 安装路径设置
# 这里统一windows的安装路径设置在当前目录下install，不用默认路径
########################################################
set(CMAKE_INSTALL_PREFIX "${CPPSCAFFOLDING_INSTALL_DIR}")

########################################################
# 第三方库参数加载
########################################################
# hiredis
find_package(hiredis)
if(hiredis_FOUND)
    message(STATUS "hiredis ${hiredis_VERSION} was installed,you can link hiredis:")
    message(STATUS "  |- target_link_libraries(your_target_name PRIVATE hiredis::hiredis)")
    message(STATUS "  |- hiredis_LIBRARIES=${hiredis_LIBRARIES}")
    message(STATUS "  |- hiredis_INCLUDE_DIRS=${hiredis_INCLUDE_DIRS}")
endif()

# redis++
find_package(redis++)
if(redis++_FOUND)
    message(STATUS "redis++ ${redis++_VERSION} was installed,you can link redis++ by shared lib:")
    message(STATUS "  |- target_link_libraries(your_target_name PRIVATE redis++::redis++)")
    message(STATUS "  |- or link static lib by:")
    message(STATUS "  |- target_link_libraries(your_target_name PRIVATE redis++::redis++_static)")
endif()

# nlohmann_json
find_package(nlohmann_json)
if(nlohmann_json_FOUND)
    message(STATUS "nlohmann_json ${nlohmann_json_VERSION} was installed,you can link nlohmann_json:")
    message(STATUS "  |- target_link_libraries(your_target_name PRIVATE nlohmann_json::nlohmann_json)")
endif()

# RapidJSON
find_package(RapidJSON)
if(RapidJSON_FOUND)
    message(STATUS "RapidJSON ${RapidJSON_VERSION} was installed,you can link RapidJSON:")
    message(STATUS "  |- target_include_directories(your_target_name \$\{RapidJSON_INCLUDE_DIR})")
    message(STATUS "  |- RapidJSON_INCLUDE_DIR=${RapidJSON_INCLUDE_DIR}")
endif()

# spdlog
find_package(spdlog)
if(spdlog_FOUND)
    message(STATUS "spdlog ${spdlog_VERSION} was installed,you can link spdlog:")
    message(STATUS "  |- target_link_libraries(your_target_name spdlog::spdlog)")
    message(STATUS "  |- or use header only by:")
    message(STATUS "  |- target_link_libraries(your_target_name spdlog::spdlog_header_only)")
endif()

# RdKafka
find_package(RdKafka)
if(RdKafka_FOUND)
    message(STATUS "RdKafka ${RdKafka_VERSION} was installed,you can link RdKafka:")
    message(STATUS "  |- target_link_libraries(your_target_name RdKafka::rdkafka)")
    message(STATUS "  |- or use RdKafka++ by:")
    message(STATUS "  |- target_link_libraries(your_target_name RdKafka::rdkafka++)")
endif()

# tinyxml2
find_package(tinyxml2)
if(tinyxml2_FOUND)
    message(STATUS "tinyxml2 ${tinyxml2_VERSION} was installed,you can link tinyxml2:")
    message(STATUS "  |- target_link_libraries(your_target_name tinyxml2::tinyxml2)")
endif()

# concurrentqueue
find_package(concurrentqueue)
if(concurrentqueue_FOUND)
    message(STATUS "concurrentqueue ${concurrentqueue_VERSION} was installed,you can link concurrentqueue:")
    message(STATUS "  |- target_link_libraries(your_target_name concurrentqueue::concurrentqueue)")
endif()

# asio
set(CPPSCAFFOLDING_ASIO_INCLUDE_DIR ${CPPSCAFFOLDING_INCLUDE_DIR}/asio)
if(EXISTS ${CPPSCAFFOLDING_ASIO_INCLUDE_DIR}/asio.hpp)
    message(STATUS "asio was installed,you can link asio:")
    message(STATUS "  |- target_include_directories(your_target_name \$\{CPPSCAFFOLDING_INCLUDE_DIR}/asio)")
else()
    set(CPPSCAFFOLDING_ASIO_INCLUDE_DIR)
endif()

# mini
set(CPPSCAFFOLDING_MINI_INCLUDE_DIR ${CPPSCAFFOLDING_INCLUDE_DIR}/mini)
if(EXISTS ${CPPSCAFFOLDING_MINI_INCLUDE_DIR}/ini.h)
    message(STATUS "mINI was installed,you can link mINI:")
    message(STATUS "  |- target_include_directories(your_target_name \$\{CPPSCAFFOLDING_MINI_INCLUDE_DIR})")
else()
    set(CPPSCAFFOLDING_MINI_INCLUDE_DIR)
endif()

# message
message(STATUS "you can import 3rdparty:")
if(hiredis_FOUND)
    message("=> target_link_libraries(your_target_name PRIVATE hiredis::hiredis)")
endif()
if(redis++_FOUND)
    message("=> target_link_libraries(your_target_name PRIVATE redis++::redis++) / target_link_libraries(your_target_name PRIVATE redis++::redis++_static)")
endif()
if(nlohmann_json_FOUND)
    message("=> target_link_libraries(your_target_name PRIVATE nlohmann_json::nlohmann_json)")
endif()
if(RapidJSON_FOUND)
    message("=> target_include_directories(your_target_name \$\{RapidJSON_INCLUDE_DIR})")
endif()
if(spdlog_FOUND)
    message("=> target_link_libraries(your_target_name spdlog::spdlog) / target_link_libraries(your_target_name spdlog::spdlog_header_only)")
endif()
if(RdKafka_FOUND)
    message("=> target_link_libraries(your_target_name RdKafka::rdkafka) / target_link_libraries(your_target_name RdKafka::rdkafka++)")
endif()
if(tinyxml2_FOUND)
    message("=> target_link_libraries(your_target_name tinyxml2::tinyxml2)")
endif()
if(CPPSCAFFOLDING_ASIO_INCLUDE_DIR)
    message("=> target_include_directories(your_target_name \$\{CPPSCAFFOLDING_INCLUDE_DIR}/asio)")
endif()
if(CPPSCAFFOLDING_ASIO_INCLUDE_DIR)
    message("=> target_include_directories(your_target_name \$\{CPPSCAFFOLDING_MINI_INCLUDE_DIR})")
endif()
if(concurrentqueue_FOUND)
    message("=> target_link_libraries(your_target_name concurrentqueue::concurrentqueue)")
endif()
# 你在此基础上，添加你的cmake文件到src目录下，即可完成一个完整项目的构建
message(STATUS "you can add your source by:add_subdirectory(src)")
# 打印所有cmake变量
#get_cmake_property(_variableNames VARIABLES)  
#foreach(_variableName ${_variableNames})  
#    message(STATUS "${_variableName} = ${${_variableName}}")  
#endforeach()  